// Websocket地址 - 修改为Spring WebSocket端点
const url = "ws://localhost:8081/api/ws";

// Websocket实例
let ws = null;

// 重连定时器实例
let reconnectTimer = null;

// 当前用户id
let currentUserId = null;

// websocket重连开关
let isReconnecting = false;

// 心跳检测定时器
let heartbeatTimer = null;

// websocket对象
const websocket = {
  // websocket建立连接
  Init(userId) {
    if (!userId) {
      console.log("WebSocket初始化失败：缺少userId");
      return;
    }

    // 保存当前用户ID
    currentUserId = userId;
    sessionStorage.setItem("ws_userId", userId);

    // 判断浏览器是否支持websocket
    if (!("WebSocket" in window)) {
      console.log("浏览器不支持websocket");
      return;
    }

    // 如果已有连接则先关闭
    if (ws) {
      this.Close();
    }

    // 创建websocket实例 - Spring WebSocket连接
    // 通常Spring WebSocket不需要在URL中传递userId，而是通过STOMP订阅或token认证
    ws = new WebSocket(url);

    //创建websocket连接成功事件
    ws.onopen = () => {
      console.log("Spring WebSocket连接成功");

      // 发送认证消息（如果需要）
      this.sendAuthentication(userId);

      // 启动心跳检测
      this.startHeartbeat();

      // 断线重连成功，将断线重连开关设置为false
      isReconnecting = false;
      clearTimeout(reconnectTimer);
      reconnectTimer = null;
    };

    // 监听WebSocket连接错误信息
    ws.onerror = (e) => {
      console.log("WebSocket数据传输发生错误", e);
      if (!isReconnecting && currentUserId) {
        this.reconnect();
      }
    };

    // 监听WebSocket接收消息 - Spring WebSocket消息格式
    ws.onmessage = (e) => {
      console.log("🚨 onmessage 被触发了！收到原始数据:", e.data);

      try {
        const messageData = JSON.parse(e.data);
        console.log("解析后的Spring WebSocket消息:", messageData);

        // 处理不同类型消息
        this.handleSpringMessage(messageData);
      } catch (error) {
        console.error("JSON解析错误:", error, "原始数据:", e.data);
        // 处理非JSON消息（如心跳响应等）
        this.handleTextMessage(e.data);
      }
    };

    // 连接关闭处理
    ws.onclose = (e) => {
      console.log("WebSocket连接关闭:", e);
      // 停止心跳检测
      this.stopHeartbeat();
      // 如果不是主动断开连接，则尝试重连
      if (!isReconnecting && currentUserId) {
        this.reconnect();
      }
    };
  },

  // 发送认证消息（Spring WebSocket通常需要认证）
  sendAuthentication(userId) {
    const authMessage = {
      type: "AUTH",
      userId: userId,
      timestamp: Date.now(),
    };
    this.Send(authMessage);
  },

  // 处理Spring WebSocket消息
  handleSpringMessage(messageData) {
    const { type, payload, destination } = messageData;

    console.log(`处理Spring消息 - 类型: ${type}, 目标: ${destination}`);

    // 根据消息类型处理
    switch (type) {
      case "CHAT":
      case "MESSAGE":
        this.handleChatMessage(payload || messageData);
        break;
      case "NOTIFICATION":
        this.handleNotificationMessage(payload || messageData);
        break;
      case "HEARTBEAT":
        console.log("收到心跳响应");
        break;
      case "ERROR":
        console.error("WebSocket错误消息:", messageData);
        break;
      default:
        // 默认处理所有消息
        this.handleGenericMessage(messageData);
    }
  },

  // 处理聊天消息
  handleChatMessage(message) {
    console.log("处理聊天消息:", message);
    this.executeCallback(message);
  },

  // 处理通知消息
  handleNotificationMessage(message) {
    console.log("处理通知消息:", message);
    this.executeCallback(message);
  },

  // 处理通用消息
  handleGenericMessage(message) {
    console.log("处理通用消息:", message);
    this.executeCallback(message);
  },

  // 处理文本消息（非JSON）
  handleTextMessage(text) {
    if (text === "pong" || text === "ok") {
      console.log("收到心跳响应");
      return;
    }
    console.log("处理文本消息:", text);
    this.executeCallback(text);
  },

  // 执行回调函数
  executeCallback(message) {
    if (
      this.onMessageCallback &&
      typeof this.onMessageCallback === "function"
    ) {
      try {
        this.onMessageCallback(message);
      } catch (error) {
        console.error("消息回调处理错误:", error);
      }
    } else {
      console.warn("消息回调函数未设置");
    }
  },

  // 启动心跳检测
  startHeartbeat() {
    this.stopHeartbeat(); // 先停止现有的
    heartbeatTimer = setInterval(() => {
      if (ws && ws.readyState === WebSocket.OPEN) {
        const heartbeat = {
          type: "HEARTBEAT",
          timestamp: Date.now(),
        };
        this.Send(heartbeat);
        console.log("发送心跳检测");
      }
    }, 30000); // 每30秒发送一次心跳
  },

  // 停止心跳检测
  stopHeartbeat() {
    if (heartbeatTimer) {
      clearInterval(heartbeatTimer);
      heartbeatTimer = null;
    }
  },

  //websocket连接关闭方法
  Close() {
    // 关闭断开重连机制
    isReconnecting = true;
    // 停止心跳检测
    this.stopHeartbeat();

    if (ws) {
      ws.close();
      ws = null;
    }

    clearTimeout(reconnectTimer);
    reconnectTimer = null;
    console.log("WebSocket连接已关闭");
  },

  //websocket发送消息方法 - 保持接口不变
  Send(data) {
    console.log("准备发送消息:", data);

    if (!ws || ws.readyState !== WebSocket.OPEN) {
      console.log(
        "无法发送消息：websocket未连接，当前状态:",
        ws ? ws.readyState : "无实例"
      );
      if (currentUserId && !isReconnecting) {
        this.reconnect();
      }
      return false;
    }

    try {
      let messageToSend = data;

      // 如果数据不是对象，尝试包装成Spring WebSocket格式
      if (typeof data !== "object") {
        messageToSend = {
          type: "MESSAGE",
          payload: data,
          timestamp: Date.now(),
        };
      }

      const msg = JSON.stringify(messageToSend);
      console.log("发送JSON消息:", msg);
      ws.send(msg);
      return true;
    } catch (error) {
      console.log("发送消息失败：", error);
      return false;
    }
  },

  //暴露websocket实例，其他地方调用这个方法即可
  getWebSocket() {
    return ws;
  },

  //新增回调函数用于处理收到的消息
  onMessageCallback: null,

  // 设置消息处理回调函数
  setMessageCallback(callback) {
    this.onMessageCallback = callback;
  },

  // 重连方法
  reconnect() {
    if (!currentUserId) {
      console.log("用户未登录，无法重连");
      return;
    }
    if (isReconnecting) {
      console.log("已在重连中，跳过本次重连");
      return;
    }

    isReconnecting = true;
    console.log("WebSocket开始重连...");

    // 清除现有定时器
    clearTimeout(reconnectTimer);

    // 使用指数退避策略
    const delay = Math.min(1000 * Math.pow(2, this.reconnectCount || 0), 30000);
    this.reconnectCount = (this.reconnectCount || 0) + 1;

    reconnectTimer = setTimeout(() => {
      console.log(`WebSocket正在重连... (第${this.reconnectCount}次)`);
      this.Init(currentUserId);
    }, delay);
  },
};

// 监听窗口关闭事件
window.addEventListener("beforeunload", () => {
  websocket.Close();
  console.log("页面关闭，WebSocket已断开");
});

// 浏览器刷新重新连接
if (performance.getEntriesByType("navigation")[0].type === "reload") {
  console.log("检测到浏览器刷新");
  const cachedUserId = sessionStorage.getItem("ws_userId");

  if (cachedUserId) {
    setTimeout(() => {
      console.log("WebSocket执行刷新重新连接...");
      websocket.Init(cachedUserId);
    }, 1000);
  }
}

// 暴露对象
export default websocket;
